package com.everyline.baselibrary.base.fragment

import android.content.Context
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.fragment.app.Fragment
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import com.blankj.utilcode.util.LogUtils

import com.everyline.baselibrary.ext.getVmClazz
import com.everyline.baselibrary.network.manager.NetState
import com.everyline.baselibrary.network.manager.NetworkStateManager
import com.everyline.baselibrary.view.MultipleStatusView
import com.everyline.baselibrary.base.viewmodel.BaseViewModel
import com.tbruyelle.rxpermissions3.RxPermissions
import java.lang.reflect.ParameterizedType

/**
 *creatd by 天天挂线
 *email:746608431@qq.com
 *on 2020/7/6
 *描述:TODO
 */
abstract class BaseVMFragment<VM : BaseViewModel, DB : ViewDataBinding> : Fragment() {


    //是否第一次加载
    private var isFirst: Boolean = true
    lateinit var mViewModel: VM
    lateinit var mViewBinding: DB
    lateinit var mActivity: AppCompatActivity
    lateinit var mContext: Context
    var mLayoutStatusView: MultipleStatusView? = null
    val mRxPermissions: RxPermissions by lazy { RxPermissions(this) }


    override fun onAttach(context: Context) {
        super.onAttach(context)
        mActivity = context as AppCompatActivity
        mContext = context

    }


    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        mViewBinding = DataBindingUtil.inflate(inflater, setLayoutId(), container, false)
        mViewBinding.lifecycleOwner = this
        return mViewBinding.root
    }


    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        isFirst = true
        mViewModel = createViewModel()
        getTitleBar()
        registorDefUIChange()
        initView(savedInstanceState)

        createObserver()
        initData()
        onVisible()
        initListener()

        retryStart()

        initRetryClickListener() //多种状态切换的view 重试点击事件


    }

    override fun onResume() {
        super.onResume()
        onVisible()

    }


    private fun initRetryClickListener() {

        mLayoutStatusView?.setOnRetryClickListener(mRetryClickListener)
    }


    open val mRetryClickListener: View.OnClickListener = View.OnClickListener {
        retryStart()
    }

    private fun registorDefUIChange() {

        mViewModel.loadingChange.showDialog.observeInFragment(this, Observer {
            showLoading(
                if (it.isEmpty()) {
                    "请求网络中..."
                } else it
            )
        })
        mViewModel.loadingChange.dismissDialog.observeInFragment(this, Observer {
            dismissLoading()
        })
    }

    private fun onVisible() {

        if (lifecycle.currentState == Lifecycle.State.STARTED && isFirst) {
            lazyLoadData()
            //在Fragment中，只有懒加载过了才能开启网络变化监听
            NetworkStateManager.instance.mNetworkStateCallback.observe(
                viewLifecycleOwner,
                Observer {
                    //不是首次订阅时调用方法，防止数据第一次监听错误
                    if (!isFirst) {
                        onNetworkStateChanged(it)
                    }
                })
            isFirst = false
        }

    }


    private fun createViewModel(): VM {

        return ViewModelProvider(this).get(getVmClazz(this))
    }

    abstract fun setLayoutId(): Int
    abstract fun getTitleBar(): Int
    abstract fun initView(savedInstanceState: Bundle?)
    abstract fun createObserver()
    open fun initData() {}
    abstract fun lazyLoadData()
    open fun onNetworkStateChanged(it: NetState?) {}
    open fun retryStart() {}
    abstract fun initListener()
    open fun onRightClickListener(v: View?) {}
    open fun onTitleClickListener(v: View?) {}
    abstract fun showLoading(message: String = "请求网络中...")

    abstract fun dismissLoading()

    /**
     * 将非该Fragment绑定的ViewModel添加 loading回调 防止出现请求时不显示 loading 弹窗bug
     * @param viewModels Array<out BaseViewModel>
     */
    protected fun addLoadingObserve(vararg viewModels: BaseViewModel) {
        viewModels.forEach { viewModel ->
            //显示弹窗
            viewModel.loadingChange.showDialog.observeInFragment(this, Observer {
                showLoading(it)
            })
            //关闭弹窗
            viewModel.loadingChange.dismissDialog.observeInFragment(this, Observer {
                dismissLoading()
            })
        }
    }

}